package com.weilele.leisure.time.ui.player

import com.google.android.exoplayer2.MediaItem
import com.weilele.leisure.time.bean.VideoDetailBean
import com.weilele.leisure.time.bean.VideoGJBean
import com.weilele.leisure.time.net.ApiInstance
import com.weilele.mvvm.okHttpClient
import com.weilele.mvvm.utils.activity.toast
import com.weilele.mvvm.utils.coroutine.createCoroutine
import com.yizisu.playerlibrary.IYzsPlayer
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch
import okhttp3.Call
import okhttp3.Request
import org.json.JSONObject

class VideoModel(
    val video: VideoDetailBean,
    val listBean: VideoDetailBean.PlayersDTO,
    val dto: VideoDetailBean.PlayersDTO.DatasDTO
) : IYzsPlayer.Model() {

    override fun getTitle(): CharSequence? {
        return "${video.title} ${dto.text}"
    }

    private val scope = lazy { createCoroutine() }

    override fun onMediaItem(uriCall: (MediaItem?, Throwable?, Boolean) -> Unit) {
        tryUrls.clear()
        overrideExtension = null
        getMediaItem(uriCall)
    }


    override fun callMediaItemWhenError(
        error: Throwable,
        uriCall: (MediaItem?, Throwable?, Boolean) -> Unit
    ) {
        super.callMediaItemWhenError(error, uriCall)
        getMediaItem(uriCall)
    }

    //从后台获取可以解析的url链接
    private var urlGjs: List<VideoGJBean>? = null

    //尝试过的url
    private val tryUrls = mutableListOf<String>()

    //网络请求，销毁的时候取消
    private var jobCall: Call? = null
    private fun parasUrl(urlCall: Function1<String?, Unit>) {
//        {
//            "code":"200",
//            "success":"1",
//            "name":"阿里资源站",
//            "type":"hls",
//            "url":"https://m3u8.tv.janan.net/m3u8cache/iqiyi/bc586956a1707355c229c7860d9dff39.m3u8",
//            "metareferer":"",
//            "player":"dplayer"
//        }
        scope.value.launch {
            val url = try {
                var realUrl: String? = null
                "正在解析播放地址".toast()
                val result = urlGjs ?: ApiInstance.getGjs().result
                urlGjs = result
                if (!result.isNullOrEmpty()) {
                    for (it in result) {
                        jobCall?.cancel()
                        val call = okHttpClient.newCall(
                            Request.Builder()
                                .url("${it.url}${dto.playUrl}")
                                .apply {
                                    it.apiheaders?.forEach {
                                        header(it.name, it.value)
                                    }
                                }
                                .build()
                        )
                        jobCall = call
                        val response = call.execute()
                        jobCall = null
                        val body = response.body?.string()
                        if (body != null) {
                            try {
                                val json = JSONObject(body)
                                if (json.has("type")) {
                                    val type = json.getString("type")
                                    overrideExtension = when (type) {
                                        "hls" -> "m3u8"
                                        else -> type
                                    }
                                }
                                if (json.has("url")) {
                                    realUrl = json.getString("url")
                                    if (!realUrl.isNullOrBlank()) {
                                        if (realUrl.startsWith("//")) {
                                            realUrl = "http:${realUrl}"
                                        }
                                        if (!tryUrls.contains(realUrl)) {
                                            break
                                        }
                                    }
                                }
                            } catch (e: Throwable) {
                                e.printStackTrace()
                            }
                        }
                    }
                }
                realUrl
            } catch (e: Throwable) {
                e.printStackTrace()
                null
            }
            urlCall.invoke(url)
        }
    }


    override fun onDestroy() {
        super.onDestroy()
        jobCall?.cancel()
        jobCall = null
        if (scope.isInitialized()) {
            scope.value.cancel()
        }
    }

    override fun onPlayModelNotThis() {
        super.onPlayModelNotThis()
        jobCall?.cancel()
        jobCall = null
        if (scope.isInitialized()) {
            scope.value.cancel()
        }
    }


    private fun getMediaItem(uriCall: (MediaItem?, Throwable?, Boolean) -> Unit) {
        val url = dto.playUrl
        if (url.endsWith("html")) {
            parasUrl {
                callUrl(it ?: url, uriCall)
            }
        } else {
            callUrl(url, uriCall)
        }
    }

    private fun callUrl(url: String, uriCall: (MediaItem?, Throwable?, Boolean) -> Unit) {
        if (tryUrls.contains(url)) {
            uriCall.invoke(null, Throwable("暂无可用播放链接"), false)
            return
        }
        uriCall.invoke(MediaItem.fromUri(url), null, false)
        tryUrls.add(url)
    }
}